package stone926.mods.more_enchantments.enchantments;

import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentTarget;
import net.minecraft.entity.AreaEffectCloudEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.AxeItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.potion.PotionUtil;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.Box;
import stone926.mods.more_enchantments.MoreEnchantmentsMod;
import stone926.mods.more_enchantments.interfaces.IAreaEffectCloudEntityFilterEntity;

import java.util.ArrayList;
import java.util.List;

public class SwordWithEffectEnchantment extends Enchantment {

  public SwordWithEffectEnchantment() {
    super(Rarity.VERY_RARE, EnchantmentTarget.WEAPON, new EquipmentSlot[]{EquipmentSlot.MAINHAND});
  }

  @Override
  public boolean isAcceptableItem(ItemStack stack) {
    return super.isAcceptableItem(stack) || stack.getItem() instanceof AxeItem;
  }

  @Override
  public boolean isTreasure() {
    return true;
  }

  @Override
  public int getMaxLevel() {
    return 3;
  }

  @Override
  public int getMinPower(int level) {
    return 10;
  }

  @Override
  public void onTargetDamaged(LivingEntity user, Entity target, int level) {
    if (!(target instanceof LivingEntity livingTarget)) return;

    ItemStack mainHandStack = user.getMainHandStack();
    List<StatusEffectInstance> effects = PotionUtil.getCustomPotionEffects(mainHandStack);
    List<StatusEffectInstance> areaEffects = new ArrayList<>();
    List<StatusEffectInstance> splashEffects = new ArrayList<>();

    NbtCompound nbt = mainHandStack.getOrCreateNbt();
    NbtList areaEffectsNbtList = nbt.getList(MoreEnchantmentsMod.MOD_ID + ":areaEffects", 10);
    NbtList splashEffectsNbtList = nbt.getList(MoreEnchantmentsMod.MOD_ID + ":splashEffects", 10);

    for (int i = 0; i < areaEffectsNbtList.size(); i++) {
      NbtCompound nbtCompound = areaEffectsNbtList.getCompound(i);
      StatusEffectInstance statusEffectInstance = StatusEffectInstance.fromNbt(nbtCompound);
      if (statusEffectInstance != null) areaEffects.add(statusEffectInstance);
    }

    for (int i = 0; i < splashEffectsNbtList.size(); i++) {
      NbtCompound nbtCompound = splashEffectsNbtList.getCompound(i);
      StatusEffectInstance statusEffectInstance = StatusEffectInstance.fromNbt(nbtCompound);
      if (statusEffectInstance != null) splashEffects.add(statusEffectInstance);
    }

    for (StatusEffectInstance e : effects) {
      livingTarget.addStatusEffect(e, user);
    }

    if (mainHandStack
      .getOrCreateNbt()
      .getBoolean(MoreEnchantmentsMod.MOD_ID + ":isFromLingeringPotion") && level >= 2) {
      AreaEffectCloudEntity effectCloud = new AreaEffectCloudEntity(
        target.getEntityWorld(),
        target.getX(), target.getY() + 0.7, target.getZ()
      );

      areaEffects.forEach(effectCloud::addEffect);

      effectCloud.setWaitTime(0);

      effectCloud.setDuration(level * 50 + AreaEffectCloudDurationBoostEnchantment.getExtraDuration(EnchantmentHelper.getLevel(MoreEnchantmentsMod.AREA_EFFECT_CLOUD_DURATION_BOOST, mainHandStack)));

      effectCloud.setRadius(level / 3F + 1.53F);
      effectCloud.setRadiusGrowth(level * 0.007F);
      effectCloud.setRadiusOnUse(Math.min(0F, -0.51F + level * 0.1F));

      effectCloud.setOwner(user);

      ((IAreaEffectCloudEntityFilterEntity) effectCloud).setEntityDoNotAffect(user.getUuid());

      target.getEntityWorld().spawnEntity(effectCloud);

      ((ServerWorld) user.getEntityWorld()).spawnParticles(ParticleTypes.CLOUD, target.getX(), target.getY() + target.getHeight() + 1, target
        .getZ(), 50, 0.5, 0.3, 0.5, 0);
    }
    if (mainHandStack.getOrCreateNbt().getBoolean(MoreEnchantmentsMod.MOD_ID + ":isFromSplashPotion") && level >= 3) {
      user.getEntityWorld()
          .getEntitiesByClass(
            LivingEntity.class,
            Box.from(user.getPos()).expand(level * 2),
            EntityPredicates.VALID_LIVING_ENTITY
          )
          .stream()
          .filter(l -> l != user)
          .filter(l -> l != livingTarget)
          .forEach(l -> {
            for (StatusEffectInstance e : splashEffects) {
              l.addStatusEffect(e, user);
              ((ServerWorld) l.getEntityWorld()).spawnParticles(
                ParticleTypes.DRAGON_BREATH,
                l.getX(), l.getY(), l.getZ(),
                80,
                0.4, 0.3, 0.4, 0
              );
            }
          });

    }

  }

}
